"""
图片类模块
"""
import pygame
from image.operations import load_img, draw_img
import text
from typing import Callable
import event
import mouse


class Image(object):
    """
    图片类
    """

    def __init__(
            self,
            img: str | pygame.Surface,
            target: pygame.Surface,
            position: tuple[float | int, float | int] = (0, 0),
            size: tuple[float | int, float | int] = None,
            is_scale: bool = False,
            rotate_degree: float | int | None = None,
            is_h_center: bool = False,
            is_v_center: bool = False,
            text_obj: text.Text = None,
            img_active: str | pygame.Surface | None = None,
    ):
        """
        图片类对象的初始化方法
        :param img: 图片
        :param target: 图片要绘制到的目标 Surface 对象
        :param position: 图片在目标 Surface 对象中绘制的位置
        :param size: 图片绘制的大小，如果为 None，则完整绘制图片
        :param is_scale: 图片是否跟随指定的图片绘制大小进行缩放，以确保图片能够完整显示
        :param rotate_degree: 指定图片的旋转角度
        :param is_h_center: 图片是否在水平方式上居中
        :param is_v_center: 图片是否在垂直方式上居中
        :param text_obj: 文本类对象
        :param img_active: 激活时的图片
        """
        self.img = img
        # 如果传入的是图片资源地址字符串，则先进行图片的加载
        if isinstance(img, str):
            self.img = load_img(img)
        self.target = target
        self.position = position
        self.size = size
        self.is_scale = is_scale
        self.rotate_degree = rotate_degree
        self.is_h_center = is_h_center
        self.is_v_center = is_v_center
        self.text_obj = text_obj
        # 如果传入了文本类对象，且图片类对象中没有指定目标 Surface 对象，
        # 将文本类对象要绘制到的目标 Surface 修改为当前图片类的图片
        if text_obj is not None and text_obj.target is None:
            self.text_obj.target = self.img
        self.surface: pygame.Surface | None = None
        self.rect: pygame.Rect | None = None
        # Image 类对象是否激活
        self.is_active = False
        # 如果在创建 Image 对象时传入了激活时的图片
        if img_active is not None:
            # 激活时的图片
            self.img_active = img_active
            # 如果传入的是图片资源地址字符串，则先进行图片的加载
            if isinstance(img_active, str):
                self.img_active = load_img(img_active)
            # 为 Image 类对象添加鼠标移动事件的默认处理函数
            self.add_listen_mouse_motion(self.__mouse_motion_default_handler)

    def draw(self):
        """
        绘制图片
        :return:
        """
        # 如果文本类对象不为空，且文本类对象的目标 Surface 为当前图片类中的图片
        if self.text_obj is not None and self.text_obj.target == self.img:
            self.text_obj.draw()
        # 需要绘制的图片
        img = self.img
        if self.is_active:
            img = self.img_active
        # 绘制当前图片类中的图片
        self.surface, self.rect = draw_img(
            img,
            self.target,
            self.position,
            self.size,
            self.is_scale,
            self.rotate_degree,
            self.is_h_center,
            self.is_v_center
        )
        # 如果文本类对象不为空，且文本类对象的目标 Surface 不是当前图片类中的图片
        if self.text_obj is not None and self.text_obj.target != self.img:
            self.text_obj.draw()

    def add_listen_mouse_motion(self, handler: Callable):
        """
        为当前图片类对象添加鼠标移动事件监听
        :param handler: 鼠标移入当前图片类的图片 Surface 中时的处理函数
        :return:
        """
        event.get_obj_listen_mouse_motion_dict()[self] = handler

    def __mouse_motion_default_handler(self, is_mouse_motion: bool, event: pygame.event.Event):
        """
        Image 类对象鼠标移动事件的默认处理函数
        :param is_mouse_motion: 鼠标是否在 Image 类对象上移动
        :param event: 事件对象
        :return:
        """
        # 鼠标在 Image 类对象上移动，激活；否则，不激活
        self.is_active = is_mouse_motion
        # 根据 Image 类对象是否激活修改鼠标样式
        if is_mouse_motion:
            mouse.set_mouse_hand()
        else:
            mouse.set_mouse_arrow()

    def add_listen_mouse_down(self, handler: Callable):
        """
        为当前图片类对象添加鼠标点击事件监听
        :param handler: 鼠标点击当前图片类的图片 Surface 中时的处理函数
        :return:
        """
        event.get_obj_listen_mouse_down_dict()[self] = handler
